package com.jprocms.module.cms.controller.admin.guestbook;

import cn.hutool.core.date.DateUtil;
import com.jpro.framework.common.pojo.CommonResult;
import com.jpro.framework.common.pojo.PageResult;
import com.jpro.framework.excel.core.util.ExcelUtils;
import com.jpro.framework.security.core.LoginUser;
import com.jpro.framework.security.core.util.SecurityFrameworkUtils;
import com.jpro.module.system.api.user.AdminUserApi;
import com.jpro.module.system.api.user.dto.AdminUserRespDTO;
import com.jpro.module.system.api.user.dto.MemberUserRespDTO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jprocms.module.cms.controller.admin.guestbook.vo.*;
import com.jprocms.module.cms.convert.guestbook.GuestbookConvert;
import com.jprocms.module.cms.dal.dataobject.guestbook.GuestbookDO;
import com.jprocms.module.cms.dal.dataobject.site.SiteDO;
import com.jprocms.module.cms.enums.EnumGuestbookStatus;
import com.jprocms.module.cms.enums.EnumIntCommonStatus;
import com.jprocms.module.cms.service.guestbook.GuestbookService;
import com.jprocms.module.cms.util.CmsContextUtil;
import com.jprocms.module.cms.util.RequestUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.List;

import static com.jpro.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.jpro.framework.common.pojo.CommonResult.success;
import static com.jprocms.module.cms.constant.CmsSysConstants.ANONYMOUS_USER_ID;
import static com.jprocms.module.cms.constant.CmsSysConstants.ANONYMOUS_USER_NAME;
import static com.jprocms.module.cms.enums.ErrorCodeConstants.PORTAL_USER_NOT_LOGIN;

@Tag(name = "管理后台 - 留言板")
@RestController("adminGuestbookController")
@RequestMapping("/cms/guestbook")
@Validated
public class GuestbookController {

    @Resource
    private GuestbookService guestbookService;
    @Resource
    private AdminUserApi adminUserApi;

    @PostMapping("/create")
    @Operation(summary = "创建留言板")
    @PreAuthorize("@ss.hasPermission('cms:guestbook:create')")
    public CommonResult<Long> createGuestbook(@Valid @RequestBody GuestbookCreateReqVO createReqVO, HttpServletRequest request) {
        SiteDO site = CmsContextUtil.getSite();
        final LoginUser user = SecurityFrameworkUtils.getLoginUser();
        Long userId;
        String nickname = ANONYMOUS_USER_NAME;
        if (user == null) {
            if (site.getSiteConfig().getGuestbook().getNeedLogin()) {
                throw exception(PORTAL_USER_NOT_LOGIN);
            }
            userId = ANONYMOUS_USER_ID;
        } else {
            userId = user.getId();
            final CommonResult<AdminUserRespDTO> userQueryResult = adminUserApi.getUser(userId);
            if (userQueryResult.isSuccess()) {
                nickname = userQueryResult.getData().getNickname();
            }
        }
        createReqVO.setSiteId(site.getId());
        String ip = RequestUtils.getRemoteAddr(request);
        createReqVO.setMsgIp(ip);
        createReqVO.setUserId(userId);
        if (StringUtils.isBlank(nickname)) {
            createReqVO.setNickname(nickname);
        }
        //后台添加无需审核
        createReqVO.setStatus(EnumGuestbookStatus.CHECKED.getStatus());
        return success(guestbookService.createGuestbook(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新留言板")
    @PreAuthorize("@ss.hasPermission('cms:guestbook:update')")
    public CommonResult<Boolean> updateGuestbook(@Valid @RequestBody GuestbookUpdateReqVO updateReqVO) {
        if (StringUtils.isNotBlank(updateReqVO.getReplyText())) {
            updateReqVO.setIsReplied(EnumIntCommonStatus.OPEN.getStatus());
            updateReqVO.setReplyUserId(SecurityFrameworkUtils.getLoginUserId());
            final CommonResult<MemberUserRespDTO> memberResp = adminUserApi.getMember(updateReqVO.getReplyUserId());
            if (memberResp.isSuccess()) {
                updateReqVO.setReplyUserName(memberResp.getData().getUsername());
            }
            if (updateReqVO.getReplyDate() == null) {
                updateReqVO.setReplyDate(DateUtil.date());
            }
        }
        guestbookService.updateGuestbook(updateReqVO);
        return success(true);
    }

    @PostMapping("/batchUpdateStatus")
    @Operation(summary = "更新留言板状态")
    @PreAuthorize("@ss.hasPermission('cms:guestbook:update')")
    public CommonResult<Boolean> batchUpdateStatus(@Valid @RequestBody GuestbookStatusVO updateReqVOs) {
        LambdaUpdateWrapper<GuestbookDO> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(GuestbookDO::getStatus, updateReqVOs.getStatus());
        wrapper.in(GuestbookDO::getId, updateReqVOs.getIds());
        guestbookService.update(new GuestbookDO(), wrapper);
        return success(true);
    }

    @PostMapping("/batchUpdateRecommend")
    @Operation(summary = "更新留言板推荐")
    @PreAuthorize("@ss.hasPermission('cms:guestbook:update')")
    public CommonResult<Boolean> batchUpdateRecommend(@Valid @RequestBody GuestbookRecommendVO updateReqVOs) {
        LambdaUpdateWrapper<GuestbookDO> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(GuestbookDO::getRecommended, updateReqVOs.getRecommended());
        wrapper.in(GuestbookDO::getId, updateReqVOs.getIds());
        guestbookService.update(new GuestbookDO(), wrapper);
        return success(true);
    }

    @PostMapping("/batchUpdateOpen")
    @Operation(summary = "更新留言板公开")
    @PreAuthorize("@ss.hasPermission('cms:guestbook:update')")
    public CommonResult<Boolean> batchUpdateOpen(@Valid @RequestBody GuestbookOpenVO updateReqVOs) {
        LambdaUpdateWrapper<GuestbookDO> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(GuestbookDO::getIsOpen, updateReqVOs.getIsOpen());
        wrapper.in(GuestbookDO::getId, updateReqVOs.getIds());
        guestbookService.update(new GuestbookDO(), wrapper);
        return success(true);
    }

    @PostMapping("/delete")
    @Operation(summary = "删除留言板")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('cms:guestbook:delete')")
    public CommonResult<Boolean> deleteGuestbook(@RequestParam("id") Long id) {
        guestbookService.deleteGuestbook(id);
        return success(true);
    }

    @PostMapping("/deleteGuestbooks")
    @Operation(summary = "批量删除留言板")
    @Parameter(name = "ids", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('cms:guestbook:delete')")
    public CommonResult<Boolean> deleteGuestbooks(@RequestBody List<Long> ids) {
        guestbookService.deleteGuestbooks(ids);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得留言板")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('cms:guestbook:query')")
    public CommonResult<GuestbookRespVO> getGuestbook(@RequestParam("id") Long id) {
        GuestbookDO guestbook = guestbookService.getGuestbook(id);
        return success(GuestbookConvert.INSTANCE.convert(guestbook));
    }

    @GetMapping("/list")
    @Operation(summary = "获得留言板列表")
    @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
    @PreAuthorize("@ss.hasPermission('cms:guestbook:query')")
    public CommonResult<List<GuestbookRespVO>> getGuestbookList(@RequestParam("ids") Collection<Long> ids) {
        List<GuestbookDO> list = guestbookService.getGuestbookList(ids);
        return success(GuestbookConvert.INSTANCE.convertList(list));
    }

    @PermitAll
    @GetMapping("/getToReplyCount")
    @Operation(summary = "获得留言板未回复数量")
    public CommonResult<Long> getGuestbookToReplyCount() {
        final Long guestbookCount = guestbookService.getGuestbookCount(CmsContextUtil.getCurrSiteId(), EnumGuestbookStatus.TO_CHECK.getStatus());
        return success(guestbookCount);
    }

    @GetMapping("/page")
    @Operation(summary = "获得留言板分页")
    @PreAuthorize("@ss.hasPermission('cms:guestbook:query')")
    public CommonResult<PageResult<GuestbookRespVO>> getGuestbookPage(@Valid GuestbookPageReqVO pageVO) {
        PageResult<GuestbookDO> pageResult = guestbookService.getGuestbookPage(pageVO);
        return success(GuestbookConvert.INSTANCE.convertPage(pageResult));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出留言板 Excel")
    @PreAuthorize("@ss.hasPermission('cms:guestbook:export')")

    public void exportGuestbookExcel(@Valid GuestbookQueryListReqVO exportReqVO,
                                     HttpServletResponse response) throws IOException {
        List<GuestbookDO> list = guestbookService.getGuestbookList(exportReqVO);
        // 导出 Excel
        List<GuestbookExcelVO> datas = GuestbookConvert.INSTANCE.convertList02(list);
        ExcelUtils.write(response, "留言板.xls", "数据", GuestbookExcelVO.class, datas);
    }

}
